//
//      Copyright Timothy Evans 2015    timothy.evans@gsecraif.org
//
//      This file is part of gsecraif.
//
//      gsecraif is free software; you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation; either version 3 of the License, or
//      (at your option) any later version.
//
// bit matrix

using namespace std;

#ifndef BITMATRIX_H
#define BITMATRIX_H

#include <iostream>
#include <algorithm>
#include <vector>
#include <iterator>

const unsigned char masks[8] = {'\x80','\x40','\x20','\x10','\x8','\x4','\x2','\x1'};
/*
    masks[0] = 10000000 = 128 = x80
    masks[1] = 01000000 = 64 = x40
    masks[2] = 00100000 = 32 = x20
    masks[3] = 00010000 = 16 = x10
    masks[4] = 00001000 = 8 = x8 
    masks[5] = 00000100 = 4 = x4
    masks[6] = 00000010 = 2 = x2
    masks[7] = 00000001 = 1 = x1
*/


class Bitmatrix {
    int bit_columns;  // number of columns in bit matrix (0 to bit_columns-1)
    int bit_rows; // number of rows in bit matrix (0 to bit_rows-1)
    vector<unsigned char> compact_bytes; // bytes holding matrix
                                         // in compact format - see doc 
public:

    unsigned int getrows(); // return bit rows in matrix

    unsigned int getcols(); // return bit cols in matrix

    unsigned int info(); // return some info (number of compact bytes)

    void getcompactbytes(vector<unsigned char> &bytes); // get compact bytes

    void setcompactbytes(vector<unsigned char> bytes); // set compact bytes

    int getexpandbytecols(); // get expanded cols (bytes)

    int getexpandrows(); // get expanded rows

    void getexpandbytes( vector<vector<unsigned char> >  &bytes); 
    // get left aligned expanded bytes matrix

    void compact( vector<vector<unsigned char> >  leftexpandedbytes); 
    // take a left aligned expanded bytes matrix and compact it in to a matrix

    void transpose( Bitmatrix &transposed); 
    // transpose matrix: bytes are overwritten with the transposed values
    // of the matrix referenced

// constructor

// bit matrix in compact bytes
Bitmatrix(int rows, int cols)  {
    unsigned int total_bits;
    unsigned int total_bytes;
    if ((rows > 0) && (cols > 0)) {
        total_bits = rows * cols;
        total_bytes = total_bits / 8;
        if (total_bits % 8) ++total_bytes;
        bit_columns = cols;
        bit_rows = rows;
        // initialize compact bytes
        for (int byte=0; byte != total_bytes; ++byte) {
            compact_bytes.push_back(0);
            }
        } // if ((rows..
    } // Bitmatrix


};  // end of class
 // ------------


#endif /* not BITMATRIX_H */
